package HLA1.federate;

/*
 *   Copyright 2007 The Portico Project
 *
 *   This file is part of portico.
 *
 *   portico is free software; you can redistribute it and/or modify
 *   it under the terms of the Common Developer and Distribution License (CDDL) 
 *   as published by Sun Microsystems. For more information see the LICENSE file.
 *   
 *   Use of this software is strictly AT YOUR OWN RISK!!!
 *   If something bad happens you do not have permission to come crying to me.
 *   (that goes for your lawyer as well)
 *
 */


import hla.rti.ArrayIndexOutOfBounds;
import hla.rti.EventRetractionHandle;
import hla.rti.LogicalTime;
import hla.rti.RTIexception;
import hla.rti.ReceivedInteraction;
import hla.rti.ReflectedAttributes;
import hla.rti.jlc.EncodingHelpers;
import hla.rti.jlc.NullFederateAmbassador;

import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.portico.impl.hla13.types.DoubleTime;

public class Federate1Ambassador extends NullFederateAmbassador
{
	public double federateTime        = 0.0;
	protected double federateLookahead   = 1.0;

	protected boolean isRegulating       = false;
	protected boolean isConstrained      = false;
	protected boolean isAdvancing        = false;

	protected boolean isAnnounced        = false;
	protected boolean isReadyToRun       = false;
	//VARIABILI INTERAZIONI RICEVUTE

	public double coda = 0;
	public double tempoD1;
	public double tempoD2;
	public boolean disk1_occupato = false;
	public boolean disk2_occupato = false;
	public boolean cpu = false;
	public int job;
	public int jobCodaDischi;
	public boolean ricevuto = false;

    
	private double convertTime( LogicalTime logicalTime )
	{
		return ((DoubleTime)logicalTime).getTime();
	}

	private void log( String message )
	{
		System.out.println( "FederateAmbassador1: " + message );
	}

	public void synchronizationPointRegistrationFailed( String label )
	{
		log( "Failed to register sync point: " + label );
	}

	public void synchronizationPointRegistrationSucceeded( String label )
	{
		log( "Successfully registered sync point: " + label );
	}

	public void announceSynchronizationPoint( String label, byte[] tag )
	{
		log( "Synchronization point announced: " + label );
		if( label.equals(Federate1.READY_TO_RUN) )
			this.isAnnounced = true;
	}

	public void federationSynchronized( String label )
	{
		log( "Federation Synchronized: " + label );
		if( label.equals(Federate1.READY_TO_RUN) )
			this.isReadyToRun = true;
	}

	public void timeRegulationEnabled( LogicalTime theFederateTime )
	{
		this.federateTime = convertTime( theFederateTime );
		this.isRegulating = true;
	}

	public void timeConstrainedEnabled( LogicalTime theFederateTime )
	{
		this.federateTime = convertTime( theFederateTime );
		this.isConstrained = true;
	}

	public void timeAdvanceGrant( LogicalTime theTime )
	{
		this.federateTime = convertTime( theTime );
		this.isAdvancing = false;
	}

	public void discoverObjectInstance( int theObject,
			int theObjectClass,
			String objectName )
	{
		log( "Discoverd Object: handle=" + theObject + ", classHandle=" +
				theObjectClass + ", name=" + objectName );
	}

    

	public void reflectAttributeValues( int theObject,
			ReflectedAttributes theAttributes,
			byte[] tag,
			LogicalTime theTime,
			EventRetractionHandle retractionHandle )
	{
		String s = EncodingHelpers.decodeString(tag);
		if(s.equalsIgnoreCase("codaD1"))
		{
			try {

				coda = EncodingHelpers.decodeDouble(theAttributes.getValue(0));
//				*********************************************************************
//				System.out.println("Ricevuto attributo codaD1: " + coda);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds ex) {
				Logger.getLogger(Federate1Ambassador.class.getName()).log(Level.SEVERE, null, ex);
			}
		}

		if(s.equalsIgnoreCase("tempoD1"))
		{
			try {
				ricevuto = true;
				disk1_occupato = false;
				tempoD1 = EncodingHelpers.decodeDouble(theAttributes.getValue(0));
//				*********************************************************************
//				System.out.println("Ricevuto attributo tempoD1: " + tempoD1+" disk1 = "+ disk1_occupato);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds ex) {
				Logger.getLogger(Federate1Ambassador.class.getName()).log(Level.SEVERE, null, ex);
			}
		}

		if(s.equalsIgnoreCase("tempoD2"))
		{
			try {
				ricevuto = true;
				disk2_occupato = false;
				tempoD2 = EncodingHelpers.decodeDouble(theAttributes.getValue(0));
//				*********************************************************************
//				System.out.println("Ricevuto attributo tempoD2: " + tempoD2+" disk2 = "+ disk2_occupato);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds ex) {
				Logger.getLogger(Federate1Ambassador.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
		if(s.equalsIgnoreCase("cpu"))
		{
			try {
				ricevuto = true;
				cpu = true;
//				jobCodaDischi = EncodingHelpers.decodeInt(theAttributes.getValue(0));
				job = EncodingHelpers.decodeInt(theAttributes.getValue(0));
//				*********************************************************************
//				System.out.println("Ricevuto attributo cpu: job = " + job+" cpu = "+ cpu);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds ex) {
				Logger.getLogger(Federate1Ambassador.class.getName()).log(Level.SEVERE, null, ex);
			}
		}


		if(s.equalsIgnoreCase("d1"))
		{
			disk1_occupato = false;
			try {
				job = EncodingHelpers.decodeInt(theAttributes.getValue(0));
				tempoD1 = EncodingHelpers.decodeDouble(theAttributes.getValue(1));
//				*********************************************************************
//				System.out.println("Ricevuto attributo d1: tempoD1 = " + tempoD1+" disk1 = "+ disk1_occupato+ " job = "+job);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds ex) {
				Logger.getLogger(Federate1Ambassador.class.getName()).log(Level.SEVERE, null, ex);
			}
		}

		if(s.equalsIgnoreCase("d2"))
		{
			disk2_occupato = false;
			try {
				job = EncodingHelpers.decodeInt(theAttributes.getValue(0));
				tempoD2 = EncodingHelpers.decodeDouble(theAttributes.getValue(1));
//				*********************************************************************
//				System.out.println("Ricevuto attributo d2: tempoD2 = " + tempoD2+" disk2 = "+ disk2_occupato+ " job = "+job);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds ex) {
				Logger.getLogger(Federate1Ambassador.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
		if(s.equalsIgnoreCase("d1Coda"))
		{
			disk1_occupato = false;
			try {
				jobCodaDischi = EncodingHelpers.decodeInt(theAttributes.getValue(0));
				tempoD1 = EncodingHelpers.decodeDouble(theAttributes.getValue(1));
//				*********************************************************************
//				System.out.println("Ricevuto attributo d1Coda: tempoD1 = " + tempoD1+" disk1 = "+ disk1_occupato+ " jobCodaDischi = "+jobCodaDischi);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds ex) {
				Logger.getLogger(Federate1Ambassador.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
		if(s.equalsIgnoreCase("d2Coda"))
		{
			disk2_occupato = false;
			try {
				jobCodaDischi = EncodingHelpers.decodeInt(theAttributes.getValue(0));
				tempoD2 = EncodingHelpers.decodeDouble(theAttributes.getValue(1));
//				*********************************************************************
//				System.out.println("Ricevuto attributo d2Coda: tempoD2 = " + tempoD2+" disk2 = "+ disk2_occupato+ " jobCodaDischi = "+jobCodaDischi);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds ex) {
				Logger.getLogger(Federate1Ambassador.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
		if(s.equalsIgnoreCase("jobInCodaDISCO1"))
		{
			ricevuto = true;
            disk1_occupato = true; 
 //           System.out.println("Ricevuto jobInCodaDisco1");
		}
		if(s.equalsIgnoreCase("jobInCodaDISCO2"))
		{
			ricevuto = true;
            disk2_occupato = true; 
 //           System.out.println("Ricevuto jobInCodaDisco2");

		}
	}

	public void receiveInteraction( int interactionClass,
			ReceivedInteraction theInteraction,
			byte[] tag )
	{
		receiveInteraction( interactionClass, theInteraction, tag, null, null );
	}

	public void receiveInteraction( int interactionClass,
			ReceivedInteraction theInteraction,
			byte[] tag,
			LogicalTime theTime,
			EventRetractionHandle eventRetractionHandle )
	{

	}

	public void removeObjectInstance( int theObject, byte[] userSuppliedTag )
	{
		log( "Object Removed: handle=" + theObject );
	}

	public void removeObjectInstance( int theObject,
			byte[] userSuppliedTag,
			LogicalTime theTime,
			EventRetractionHandle retractionHandle )
	{
		log( "Object Removed: handle=" + theObject );
	}

}
